package com.sixbro.websocket.config;

import com.sixbro.websocket.service.EchoService;
import com.sixbro.websocket.service.EchoServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.messaging.support.ExecutorSubscribableChannel;
import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

/**
 * WebScoket配置处理器
 *
 * @author: Mr.Lu
 * @since: 2022/1/16 11:51
 */
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(echoWebSocketHandler(), "/echo")
                .setAllowedOrigins("*")
                .withSockJS()
                .setHeartbeatTime(30000)
                .setSessionCookieNeeded(true)
                .setTaskScheduler(taskScheduler());
    }

    /**
     * ServerEndpointExporter 作用
     *
     * 这个Bean会自动注册使用@ServerEndpoint注解声明的websocket endpoint
     *
     * @return
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

    @Bean
    public WebSocketHandler echoWebSocketHandler() {
        return new EchoWebSocketHandler(echoService());
    }

    @Bean
    public EchoService echoService() {
        return new EchoServiceImpl("Did you say \"%s\"?");
    }

    @Bean
    public ConcurrentTaskScheduler taskScheduler() {
        ConcurrentTaskScheduler task = new ConcurrentTaskScheduler();
        task.scheduleAtFixedRate(new SockTaskRunner(), 1000*60*SocketSessionInfo.SESSION_INVALID);
        return task;
    }

    @Bean
    public SimpMessagingTemplate messageTemplate(){
        return new SimpMessagingTemplate(new ExecutorSubscribableChannel());
    }
}
